﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace LunarSF.SHomeWorkshop.LunarMarkdownEditor.Utils
{
    class ImageLinkTool
    {
        /// <summary>
        /// 从提供的文本中找出包含的所有图像链接字符串的完整表示形式。
        /// </summary>
        /// <param name="srcText">源文本。</param>
        /// <returns>如果提供的文本中没有图像链接，返回 null。否则返回 List&lt;string&gt;。</returns>
        public static List<string> GetImageLinksFromText(string srcText)
        {
            if (string.IsNullOrWhiteSpace(srcText)) return null;
            Regex reg = new Regex(@"[!]\[.*?\]\([^:""]{1,}?([ \t].*?){0,1}\)");

            var matches = reg.Matches(srcText);
            if (matches.Count > 0)
            {
                List<string> result = new List<string>();
                foreach (Match m in matches)
                {
                    result.Add(m.Value);
                }
                return result;
            }
            return null;
        }

        /// <summary>
        /// 根据图像链接字符串，取出图像的完整物理磁盘路径。
        /// </summary>
        /// <param name="imageLinkText">完整的图像链接文本，其中必须保证图像相对路径字符串真实有效，其余信息会被忽略。</param>
        /// <param name="markdownFilePath">图像链接所在的 Markdown 文件的路径。</param>
        public static string GetRealPathFromImagelink(string imageLinkText, string markdownFilePath)
        {
            var reg = new Regex(@"(?<=([!]\[.*?\]\())[^:""]{1,}?(?=(([ \t].*?){0,1}\)))");
            var match = reg.Match(imageLinkText);
            if (match.Success == false)
            {
                if (imageLinkText.Contains(new DirectoryInfo(Globals.PathOfWorkspace).Name))
                {
                    var indexofLeft = imageLinkText.IndexOf("](");
                    if (imageLinkText.StartsWith("![") && indexofLeft > 1)
                    {
                        var indexofRight1 = imageLinkText.IndexOf(")", indexofLeft + 2);
                        var indexofRight2 = imageLinkText.IndexOf("\"", indexofLeft + 2);
                        if (indexofRight2 < 0)
                        {
                            if (indexofRight1 > indexofLeft + 2)
                            {
                                return GetRealPathFromRelativeImagePath(imageLinkText.Substring(indexofLeft + 2, indexofRight1 - indexofLeft - 2), markdownFilePath);
                            }
                        }
                        else if (indexofRight2 < indexofRight1)
                        {
                            if (indexofRight2 > indexofLeft + 2)
                            {
                                return GetRealPathFromRelativeImagePath(imageLinkText.Substring(indexofLeft + 2, indexofRight2 - indexofLeft - 2), markdownFilePath);
                            }
                        }
                    }
                }
                return "";
            }

            return GetRealPathFromRelativeImagePath(match.Value, markdownFilePath);
        }

        /// <summary>
        /// 根据图像链接字符串中的相对路径，取出图像的完整物理磁盘路径。
        /// </summary>
        /// <param name="imgRelativePath">图像链接中的相对路径。</param>
        /// <param name="markdownFilePath">图像链接所在的 Markdown 文件的路径。</param>
        public static string GetRealPathFromRelativeImagePath(string imgRelativePath, string markdownFilePath)
        {
            var splitter = new char[] { '/', '\\', };
            imgRelativePath = imgRelativePath.Trim(splitter);
            var pieces = imgRelativePath.Split(splitter, StringSplitOptions.RemoveEmptyEntries);
            var thisPathInfo = new FileInfo(markdownFilePath);
            var imgDirectoryInfo = thisPathInfo.Directory;
            foreach (var piece in pieces)
            {
                if (piece == ".") continue;
                if (piece == "..")
                {
                    imgDirectoryInfo = imgDirectoryInfo.Parent;
                    continue;
                }
                var path = imgDirectoryInfo.FullName;
                imgDirectoryInfo = new DirectoryInfo(path + (path.EndsWith("/") ? "" : "/") + piece);
            }
            return imgDirectoryInfo.FullName;
        }

        /// <summary>
        /// 根据完整路径求出在指定 Markdown 文件中引用某个图像文件需要的 Html 相对路径。
        /// 注意：两个完整路径必须都属于当前工作区。
        /// </summary>
        /// <param name="imagePath">当前工作区中的图像文件的完整路径。</param>
        /// <param name="mdFilePath">当前工作区中 Markdown 文件的完整路径。</param>
        /// <returns>返回类似 ../../xxx.png 的相对路径。</returns>
        public static string GetImageRelativePath(string imagePath, string mdFilePath)
        {
            try
            {
                if (File.Exists(imagePath) == false || File.Exists(mdFilePath) == false)
                    return null;
                var wp = Globals.PathOfWorkspace.ToLower();
                if (imagePath.ToLower().StartsWith(wp) == false)
                {
                    return "图像链接必须属于当前工作区！";
                }

                if (mdFilePath.ToLower().StartsWith(wp) == false)
                {
                    return "Markdown 文件必须属于当前工作区！";
                }

                string[] imgPieces = imagePath.ToLower().Split(new char[] { '\\', '/', }, StringSplitOptions.RemoveEmptyEntries);
                string[] mdPieces = mdFilePath.ToLower().Split(new char[] { '\\', '/', }, StringSplitOptions.RemoveEmptyEntries);

                int min_length = Math.Min(imgPieces.Length, mdPieces.Length);
                string last_common_ancestor = "";
                int start_diff = min_length - 1;
                for (int i = 0; i < min_length; i++)
                {
                    if (imgPieces[i] == mdPieces[i])
                    {
                        last_common_ancestor += imgPieces[i];
                        last_common_ancestor += "\\";
                    }
                    else
                    {
                        start_diff = i;
                        break;
                    }
                }

                var sb = new StringBuilder();
                if (start_diff >= 1)
                {
                    for (int i = start_diff - 1; i < mdPieces.Length - 2; i++)
                    {
                        sb.Append("../");
                    }
                }

                return sb + imagePath.Substring(last_common_ancestor.Length).Replace("\\", "/");
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
    }
}
